package com.ruoyi.ncpsy.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.ncpsy.domain.NcpsyEventLog;
import com.ruoyi.ncpsy.mapper.NcpsyEventLogMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.config.Config;
import org.fisco.bcos.sdk.config.ConfigOption;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.crypto.keypair.ECDSAKeyPair;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.ncpsy.mapper.NcpsyCropFertilizerMapper;
import com.ruoyi.ncpsy.domain.NcpsyCropFertilizer;
import com.ruoyi.ncpsy.service.INcpsyCropFertilizerService;

/**
 * 作物与肥料记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-08-30
 */
@Service
public class NcpsyCropFertilizerServiceImpl implements INcpsyCropFertilizerService 
{
    @Autowired
    private NcpsyCropFertilizerMapper ncpsyCropFertilizerMapper;

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private NcpsyEventLogMapper ncpsyEventLogMapper;
    /**
     * 查询作物与肥料记录
     * 
     * @param fertRecordId 作物与肥料记录主键
     * @return 作物与肥料记录
     */
    @Override
    public NcpsyCropFertilizer selectNcpsyCropFertilizerByFertRecordId(Long fertRecordId)
    {
        return ncpsyCropFertilizerMapper.selectNcpsyCropFertilizerByFertRecordId(fertRecordId);
    }

    /**
     * 查询作物与肥料记录列表
     * 
     * @param ncpsyCropFertilizer 作物与肥料记录
     * @return 作物与肥料记录
     */
    @Override
    public List<NcpsyCropFertilizer> selectNcpsyCropFertilizerList(NcpsyCropFertilizer ncpsyCropFertilizer)
    {
        return ncpsyCropFertilizerMapper.selectNcpsyCropFertilizerList(ncpsyCropFertilizer);
    }

    /**
     * 新增作物与肥料记录
     * 
     * @param ncpsyCropFertilizer 作物与肥料记录
     * @return 结果
     */
    @Override
    public int insertNcpsyCropFertilizer(NcpsyCropFertilizer ncpsyCropFertilizer) throws Exception {
        ncpsyCropFertilizer.setCreateTime(DateUtils.getNowDate());
        
        // 创建临时目录和文件，解决JAR包内资源访问问题
        Path tempDir = Files.createTempDirectory("bcos-config-");
        File tempConfigFile = new File(tempDir.toFile(), "config-example.toml");
        File tempCertDir = new File(tempDir.toFile(), "conf");
        File tempAbiDir = new File(tempDir.toFile(), "abi");
        tempCertDir.mkdirs();
        tempAbiDir.mkdirs();
        
        // 添加日志输出，确认临时目录创建成功
        System.out.println("Created temporary directory: " + tempDir.toAbsolutePath());
        System.out.println("Temporary ABI directory: " + tempAbiDir.getAbsolutePath());
        
        try {
            // 复制配置文件到临时目录
            copyResourceToFile("BOOT-INF/classes/config-example.toml", tempConfigFile);
            
            // 复制证书文件到临时目录
            copyResourceToFile("BOOT-INF/classes/conf/ca.crt", new File(tempCertDir, "ca.crt"));
            copyResourceToFile("BOOT-INF/classes/conf/sdk.crt", new File(tempCertDir, "sdk.crt"));
            copyResourceToFile("BOOT-INF/classes/conf/sdk.key", new File(tempCertDir, "sdk.key"));
            
            // 复制ABI文件到临时目录
            copyResourceToFile("BOOT-INF/classes/abi/CropFertilizerContract.abi", new File(tempAbiDir, "CropFertilizerContract.abi"));
            
            // 读取配置文件内容，修改证书路径为临时目录中的路径
            String configContent = new String(Files.readAllBytes(tempConfigFile.toPath()));
            configContent = configContent.replace("certPath = \"conf\"", "certPath = \"" + tempCertDir.getAbsolutePath() + "\"");
            Files.write(tempConfigFile.toPath(), configContent.getBytes());
            
            // 使用修改后的配置文件初始化BcosSDK
            ConfigOption config = Config.load(tempConfigFile.getAbsolutePath());
            BcosSDK sdk = new BcosSDK(config);
        // 获取Client对象，此处传入的群组ID为1
            ncpsyCropFertilizerMapper.insertNcpsyCropFertilizer(ncpsyCropFertilizer);
            Client client = sdk.getClient(Integer.valueOf(1));
            long user_id = ncpsyCropFertilizer.getUserId();
            String hash = sysUserMapper.selecthashById(user_id);
            ECDSAKeyPair ecdsaKeyPair = new ECDSAKeyPair();
            CryptoKeyPair keyPair = ecdsaKeyPair.createKeyPair(hash);
            AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, keyPair, tempAbiDir.getAbsolutePath(), "");
            
            // 添加日志输出，确认ABI路径
            System.out.println("Using ABI path for TransactionProcessor: " + tempAbiDir.getAbsolutePath());
            // 创建调用交易函数的参数，此处为传入一个参数
            List<Object> params = new ArrayList<>();
            String fert_record_id = ncpsyCropFertilizer.getFertRecordId().toString();
            String fertilizer_id = ncpsyCropFertilizer.getFertilizerId().toString();
            String crop_event_id = ncpsyCropFertilizer.getCropEventId().toString();
            String fertilization_date = ncpsyCropFertilizer.getFertilizationDate().toString();
            params.add(fert_record_id);
            params.add(fertilizer_id);
            params.add(crop_event_id);
            params.add(fertilization_date);
            TransactionResponse transactionResponse = transactionProcessor.sendTransactionAndGetResponseByContractLoader("CropFertilizerContract", "0x05ad313435a21fc0e0689bc100e1cdd3cc75a578", "insert", params);
            //获取交易哈希
            String transactionHash = transactionResponse.getTransactionReceipt().getTransactionHash();
            NcpsyCropFertilizer ncpsyCropFertilizer1 = new NcpsyCropFertilizer();
            ncpsyCropFertilizer1.setHash(transactionHash);
            ncpsyCropFertilizer1.setFertRecordId(ncpsyCropFertilizer.getFertRecordId());
            ncpsyCropFertilizerMapper.updateNcpsyCropFertilizer(ncpsyCropFertilizer1);

            //记录施肥事件日志
            NcpsyEventLog ncpsyEventLog = new NcpsyEventLog();
            ncpsyEventLog.setCropEventId(ncpsyCropFertilizer.getCropEventId());
            ncpsyEventLog.setEventType("施肥事件");
            //把时间格式化
            ncpsyEventLog.setCreateTime(DateUtils.parseDate(ncpsyCropFertilizer.getCreateTime()));

            String eventDescription = "该作物在"+DateUtils.parseDateToStr("yyyy-MM-dd", ncpsyCropFertilizer.getFertilizationDate())  + "进行了施肥操作，使用肥料编号为：" + ncpsyCropFertilizer.getFertilizerId() + "进行了方法为"+ ncpsyCropFertilizer.getFertilizationMethod() + "的施肥,施肥量为"+ ncpsyCropFertilizer.getFertilizationAmount() + " " + ncpsyCropFertilizer.getAmountUnit();
            ncpsyEventLog.setEventDescription(eventDescription);
            ncpsyEventLog.setCreateTime(ncpsyCropFertilizer.getCreateTime());
            ncpsyEventLogMapper.insertNcpsyEventLog(ncpsyEventLog);
            
            return 1;
        } finally {
            // 清理临时文件
            deleteRecursively(tempDir.toFile());
        }
    }

    /**
     * 修改作物与肥料记录
     * 
     * @param ncpsyCropFertilizer 作物与肥料记录
     * @return 结果
     */
    @Override
    public int updateNcpsyCropFertilizer(NcpsyCropFertilizer ncpsyCropFertilizer)
    {
        ncpsyCropFertilizer.setUpdateTime(DateUtils.getNowDate());
        return ncpsyCropFertilizerMapper.updateNcpsyCropFertilizer(ncpsyCropFertilizer);
    }

    /**
     * 批量删除作物与肥料记录
     * 
     * @param fertRecordIds 需要删除的作物与肥料记录主键
     * @return 结果
     */
    @Override
    public int deleteNcpsyCropFertilizerByFertRecordIds(Long[] fertRecordIds)
    {
        return ncpsyCropFertilizerMapper.deleteNcpsyCropFertilizerByFertRecordIds(fertRecordIds);
    }

    /**
     * 删除作物与肥料记录信息
     * 
     * @param fertRecordId 作物与肥料记录主键
     * @return 结果
     */
    @Override
    public int deleteNcpsyCropFertilizerByFertRecordId(Long fertRecordId)
    {
        return ncpsyCropFertilizerMapper.deleteNcpsyCropFertilizerByFertRecordId(fertRecordId);
    }
    
    /**
     * 将类路径下的资源文件复制到临时文件
     * 
     * @param resourcePath 资源路径
     * @param targetFile 目标文件
     * @throws IOException IO异常
     */
    private void copyResourceToFile(String resourcePath, File targetFile) throws IOException {
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourcePath);
             OutputStream outputStream = new FileOutputStream(targetFile)) {
            
            if (inputStream == null) {
                throw new IOException("Resource not found: " + resourcePath);
            }
            
            // 添加日志输出，以便调试
            System.out.println("Copying resource: " + resourcePath + " to " + targetFile.getAbsolutePath());
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            
            // 确认文件复制成功
            System.out.println("Successfully copied resource: " + resourcePath);
        }
    }
    
    /**
     * 递归删除文件或目录
     * 
     * @param file 要删除的文件或目录
     */
    private void deleteRecursively(File file) {
        if (file == null) {
            return;
        }
        
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                for (File child : children) {
                    deleteRecursively(child);
                }
            }
        }
        
        file.delete();
    }
}
